<?php
namespace qhweb\phpsm\ecc;

/**
 * Hex2ByteBuf 十六进制与字节数组互转工具类
 *
 * 提供将 GMP 大整数转换为字节数组、字节数组与十六进制字符串互转、以及半字节到 ASCII 十六进制字符的映射等功能。
 * 适用于椭圆曲线密码学（ECC）等场景下的数据编解码处理。
 *
 * @package     qhweb\phpsm\ecc
 * @author      qhweb
 * @version     1.0.0
 */
class Hex2ByteBuf
{
    /**
     * 将 GMP 大整数转换为字节数组（大端）
     *
     * @param  \GMP|string|int $GmpData 输入的 GMP 数值（可为 GMP 对象、整数字符串或整数）
     * @return array 字节数组（每个元素为 0~255 的整数）
     */
    public static function ConvertGmp2ByteArray($GmpData)
    {
        $HexStr = gmp_strval($GmpData, 16);
        $OutBuf = array();
        $OutBuf = Hex2ByteBuf::HexStringToByteArray($HexStr);
        return $OutBuf;
    }
    /**
     * 将字节数组转换为十六进制字符串
     *
     * @param  array    $b      字节数组（每个元素为 0~255 的整数）
     * @param  int|null $nlen   要转换的字节长度；为 null 时转换整个数组
     * @return string 十六进制字符串（小写，不含 0x 前缀）
     */
    public static function ByteArrayToHexString($b, $nlen = null)
    {
        $outstring = array();
        $nlen = $nlen === null ? count($b) : $nlen;
        for ($n = 0; $n < $nlen; $n++) {
            $outstring[] = Hex2ByteBuf::myhex($b[$n]);
        }
        return implode("", $outstring);
    }

    /**
     * 将 0~255 的整数转换为两位大写十六进制字符
     *
     * @param  int|float $indata 输入字节（将强制转换为整数）
     * @return string 两位大写十六进制字符（例如 255 => "FF"）
     * @throws \InvalidArgumentException 当输入不在 0~255 范围内时抛出
     */
    private static function myhex($indata): string
    {
        $b = (int)$indata; // 显式转为整数，消除隐式转换告警
        if ($b < 0 || $b > 255) {
            throw new \InvalidArgumentException('myhex 输入必须在 0~255 之间');
        }
        $hi = ($b >> 4) & 0x0F;
        $lo = $b & 0x0F;
        return chr($hi < 10 ? $hi + 0x30 : $hi + 0x41 - 10) . chr($lo < 10 ? $lo + 0x30 : $lo + 0x41 - 10);
    }

    /**
     * 将十六进制字符串转换为字节数组（大端）
     *
     * 若输入长度为奇数，会在左侧补 0 后再按两位一组解析。
     *
     * @param  string $InString 十六进制字符串（可含或不含 0x 前缀，不区分大小写）
     * @return array  字节数组（每个元素为 0~255 的整数）
     */

    public static function HexStringToByteArray($InString)
    {
        for (
            $m = strlen($InString);
            $m < 64;
            $m++
        ) {
            $InString = '0' . $InString;
        }

        $nlen = 0;
        $n = 0;
        $i = 0;
        $temp = '';
        $nlen = strlen($InString);

        for (
            $n = 0;
            $n < $nlen;
            $n = $n + 2
        ) {
            $temp = substr($InString, $n, 2);
            $temp = '0x' . $temp;
            $b[$i] = hexdec($temp);
            $i = $i + 1;
        }
        return $b;
    }

     /**
     * 将十六进制字符串转换为字节数组（大端，别名方法）
     *
     * 行为与 HexStringToByteArray 一致，保留以兼容现有调用。
     *
     * @param  string $InString 十六进制字符串
     * @return array  字节数组（每个元素为 0~255 的整数）
     */

    public static function HexStringToByteArray2($InString)
    {
        $nlen = 0;
        $n = 0;
        $i = 0;
        $temp = '';
        $nlen = strlen($InString);
        for (
            $n = 0;
            $n < $nlen;
            $n = $n + 2
        ) {
            $temp = substr($InString, $n, 2);
            $temp = '0x' . $temp;
            $b[$i] = hexdec($temp);
            $i = $i + 1;
        }

        return $b;
    }
}